/* Console.java
 * A Displayable that uses a Canvas to display an alphanumeric console.
 * 
 * © 2007 David Given.
 *
 * $Id: Console.java 4 2007-06-25 15:26:37Z david.given $
 */

package com.cowlark.cowcalc;

import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

public class Console extends Canvas
{
	Font font;
	int pwidth, pheight;
	int cwidth, cheight;
	int width, height;
	char[] buffer;
	int cursorx, cursory;
	Timer presstimer;
	TimerTask presstimertask;
	
	Console()
	{
		font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL);
		cwidth = font.charWidth('m');
		cheight = font.getHeight();

		pwidth = getWidth();
		pheight = getHeight();
		
		width = pwidth / cwidth;
		height = pheight / cheight;
		buffer = new char[width*height];
	}
	
	public int getWidth()
	{
		return super.getWidth();
	}
	
	public int getHeight()
	{
		return super.getHeight();
	}
	
	public int getWidthChars()
	{
		return width;
	}
	
	public int getHeightChars()
	{
		return height;
	}
	
	public int getX()
	{
		return cursorx;
	}
	
	public int getY()
	{
		return cursory;
	}
	
	protected void paint(Graphics g)
	{
		int clipy = g.getClipY();
		int cliph = g.getClipHeight();
		int top = clipy / cheight;
		int bottom = (clipy+cliph) / cheight;
		if (top < 0)
			top = 0;
		if (bottom > height)
			bottom = height;
		
		g.setColor(0xFFFFFF);
		g.fillRect(0, top*cheight, pwidth, (bottom-top)*cheight);
		
		g.setColor(0x000000);
		g.setFont(font);
		
		for (int y=top; y<bottom; y++)
			for (int x=0; x<width; x++)
			{
				char c = buffer[y*width + x];
				if (c > 0)
				{
					g.drawChar(c, x*cwidth + (cwidth/2), y*cheight,
							Graphics.TOP|Graphics.HCENTER);
				}
			}
	}

	void repaintLine(int y)
	{
		repaint(0, y*cheight, pwidth, cheight);
	}
	
	void moveTo(int x, int y)
	{
		cursorx = x;
		cursory = y;
		if (cursorx >= width)
			cursorx = width-1;
		if (cursory >= height)
			cursory = height-1;
	}
	
	void writeAt(int x, int y, char c)
	{
		buffer[y*width + x] = c;
	}
	
	void newline()
	{
		cursorx = 0;
		cursory++;
		if (cursory == height)
		{
			cursory = height - 1;
			System.arraycopy(buffer, width, buffer, 0, width*(height-1));
			for (int x=0; x<width; x++)
				buffer[(height-1)*width + x] = 0;
		}
	}
	
	void write(char c)
	{
		if (c >= 32)
		{
			buffer[cursory*width + cursorx] = c;
			cursorx++;
		}
		
		if ((cursorx == width) || (c == '\n'))
			newline();
	}
	
	void write(String s)
	{
		for (int i=0; i<s.length(); i++)
			write(s.charAt(i));
		repaint();
	}
	
	protected void keyPressed(final int code)
	{
		presstimertask = new TimerTask()
		{
			public void run()
			{
				Main.getInstance().keypress(true, (char) code);
				presstimer = null;
			}
		};
		
		presstimer = new Timer();
		presstimer.schedule(presstimertask, 500);
	}
	
	protected void keyReleased(int code)
	{
		if (presstimertask != null)
			presstimertask.cancel();

		if (presstimer != null)
		{
			presstimer = null;
			Main.getInstance().keypress(false, (char) code);
		}
	}
}
